﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.ServiceModel.Activation;
using WcfServicioWeb.BusinessEntity;
using WcfServicioWeb.BusinessEntity.Fabricas;
using WcfServicioWeb.BusinessEntity.Ambiente;
using WcfServicioWeb.BusinessEntity.Tanque;
using Terrae.Logica.FabricaLogica;
using Terrae.Clases.FabricaClase;
using Terrae.Logica.Comandos;

namespace WcfServicioWeb
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class ServicioImplementador : IServicioImplementadorRest, IServicioImplementadorSoap
    {
        #region Implementacion REST

        public int IniciarComunicacion(int aplicacion)
        {
            return 0;
        }
        /// <summary>
        /// Solicitamos abrir o cerrar el techo del invernadero
        /// </summary>
        /// <returns></returns>
        public Luminocidad SolicitarAbrirCerrarTecho(int idInvernadero)
        {
            // creamos una instancia de un objeto del tipo "Luminocidad"
            Luminocidad luminocidad = (Luminocidad)FabricaBusinessEntity.CrearLuminocidad();
            Terrae.Clases.Arduino arduino = new Terrae.Clases.Arduino("COM5", 9600);
            string resultado = "";

            try
            {
                // datos de la Luminocidad
                arduino.DigitalReadWrite("3");
                luminocidad.set_nombre("Luminocidad");
                luminocidad.setMedicion(arduino.ValorRetornado.ToString());
                arduino.DigitalReadWrite("3.5");

                if (arduino.ValorRetornado != null && !arduino.ValorRetornado.ToString().Equals(""))
                    luminocidad.setStatus("abierto");
                else
                    luminocidad.setStatus("cerrado");

                resultado = arduino.ValorRetornado.ToString();
            }
            catch (Exception ex)
            {
                resultado = null;
                //throw new FormatException("Ocurrio un error", ex);
            }
            // verificamos la respuesta
            if (resultado != null && !resultado.Equals(""))
            {
                return luminocidad;
            }
            else // sino,
            {
                return null;
            }

        }

        /// <summary>
        /// Solicitar regar las plantas con agua
        /// </summary>
        /// <returns></returns>
        public TanqueAgua SolicitarRegarConAgua(int idInvernadero)
        {
            // creamos una instancia de un objeto del tipo "TanqueAgua"
            TanqueAgua tanqueAgua = (TanqueAgua)FabricaBusinessEntity.CrearTanqueAgua();
            // creamos una instancia de un objeto del tipo "Luminocidad"
            Terrae.Clases.Arduino arduino = new Terrae.Clases.Arduino("COM5", 9600);
            string resultado = "";

            try
            {
                // datos del tanque de agua
                arduino.DigitalReadWrite("5");
                tanqueAgua.set_nombre("TanqueAgua");
                tanqueAgua.setStatus("Open");
                if (arduino.ValorRetornado != null && !arduino.ValorRetornado.ToString().Equals(""))
                {
                    resultado = arduino.ValorRetornado.ToString();
                    tanqueAgua.setCantidad(arduino.ValorRetornado.ToString());
                }
                else
                    resultado = null;
                               
            }
            catch (Exception ex)
            {
                resultado = null;
                //throw new FormatException("Ocurrio un error", ex);
            }
            // verificamos la respuesta
            if (resultado != null && !resultado.Equals(""))
            {
                return tanqueAgua;
            }
            else // sino,
            {
                return null;
            }

        }

        /// <summary>
        /// Solicitar regar las plantas con fertilizantes
        /// </summary>
        /// <returns></returns>
        public TanqueLiquidoEspecial SolicitarRegarConFertilizante(int idInvernadero)
        {
            // creamos una instancia de un objeto del tipo "TanqueLiquidoEspecial"
            TanqueLiquidoEspecial tanqueLiquidoEspecial = (TanqueLiquidoEspecial)FabricaBusinessEntity.CrearTanqueLiquidoEspecial();
            Terrae.Clases.Arduino arduino = new Terrae.Clases.Arduino("COM5", 9600);
            string resultado = "";

            try
            {
                // datos del tanque de agua
                arduino.DigitalReadWrite("6");
                tanqueLiquidoEspecial.set_nombre("TanqueLiquidoEspecial");
                tanqueLiquidoEspecial.setStatus("Open");
                if (arduino.ValorRetornado != null && !arduino.ValorRetornado.ToString().Equals(""))
                {
                    resultado = arduino.ValorRetornado.ToString();
                    tanqueLiquidoEspecial.setCantidad(arduino.ValorRetornado.ToString());
                }
                else
                    resultado = null;
            }
            catch (Exception ex)
            {
                resultado = null;
                //throw new FormatException("Ocurrio un error", ex);
            }
            // verificamos la respuesta
            if (resultado != null && !resultado.Equals(""))
            {
                return tanqueLiquidoEspecial;
            }
            else // sino,
            {
                return null;
            }

        }

        public Invernadero SolicitarDatosInvernadero(int idInvernadero)
        {
           // Terrae.Clases.Arduino arduino = new Terrae.Clases.Arduino("COM5", 9600);
            // creamos una instancia de un objeto del tipo "Invernadero"
            Invernadero invernadero = (Invernadero)FabricaBusinessEntity.CrearInvernadero();
            // creamos una instancia de un objeto del tipo "Humedad"
            Humedad humedad         = (Humedad)FabricaBusinessEntity.CrearHumedad();
            // creamos una instancia de un objeto del tipo "Temperatura"
            Temperatura temperatura = (Temperatura)FabricaBusinessEntity.CrearTemperatura();
            // creamos una instancia de un objeto del tipo "Luminocidad"
            Luminocidad luminocidad = (Luminocidad)FabricaBusinessEntity.CrearLuminocidad();
            // creamos una instancia de un objeto del tipo "Acidez"
            Acidez acidez           = (Acidez)FabricaBusinessEntity.CrearAcidez();
            // creamos una instancia de un objeto del tipo "TanqueAgua"
            TanqueAgua tanqueAgua   = (TanqueAgua)FabricaBusinessEntity.CrearTanqueAgua();
            // creamos una instancia de un objeto del tipo "TanqueLiquidoEspecial"
            TanqueLiquidoEspecial tanqueLiquidoEspecial = (TanqueLiquidoEspecial)FabricaBusinessEntity.CrearTanqueLiquidoEspecial();

            try
            {
                // datos de la humedad
               // arduino.DigitalReadWrite("1");
                humedad.set_nombre("Humedad");
              //  humedad.setMedicion(arduino.ValorRetornado.ToString());
                humedad.setMedicion("80");

                // datos de la temperatura
               // arduino.DigitalReadWrite("2");
                temperatura.set_nombre("Temperatura");
                //temperatura.setMedicion(arduino.ValorRetornado.ToString());
                temperatura.setMedicion("25");

                // datos de la Luminocidad
               // arduino.DigitalReadWrite("3");
                luminocidad.set_nombre("Luminocidad");
               // luminocidad.setMedicion(arduino.ValorRetornado.ToString());
                luminocidad.setMedicion("200");
               // arduino.DigitalReadWrite("3.5");
               // luminocidad.setStatus(arduino.ValorRetornado.ToString());
                luminocidad.setStatus("Open");

                // datos de la Acidez
               // arduino.DigitalReadWrite("4");
                acidez.set_nombre("Acidez");
               // acidez.setMedicion(arduino.ValorRetornado.ToString());
                acidez.setMedicion("50");

                // datos del tanque de agua
               // arduino.DigitalReadWrite("5");
                tanqueAgua.set_nombre("TanqueAgua");
                tanqueAgua.setStatus("Open");
               // tanqueAgua.setCantidad(arduino.ValorRetornado.ToString());
                tanqueAgua.setCantidad("20");

                // datos del tanque de agua
              //  arduino.DigitalReadWrite("6");
                tanqueLiquidoEspecial.set_nombre("TanqueLiquidoEspecial");
                tanqueLiquidoEspecial.setStatus("Open");
                //tanqueLiquidoEspecial.setCantidad(arduino.ValorRetornado.ToString());
                tanqueLiquidoEspecial.setCantidad("30");

                invernadero._humedad = humedad;
                invernadero._temperatura = temperatura;
                invernadero._luminocidad = luminocidad;
                invernadero._acidez = acidez;
                invernadero._tanqueAgua = tanqueAgua;
                invernadero._tanqueLiquidoEspecial = tanqueLiquidoEspecial;
            }
            catch (Exception ex)
            {
                invernadero = null;
                //throw new FormatException("Ocurrio un error", ex);
            }
            // retornamos un objeto del tipo "Invernadero"
            return invernadero;
        }

        /// <summary>
        /// implementacion del metodo para verificar que el usuario suministrado existe
        /// o no
        /// </summary>
        /// <param name="cliente"></param>
        /// <returns>String</returns>
        public Cliente solicitarConfirmacionCliente(Cliente cliente)
        {
            //Obtenemos una instancia del tipo "Persona" mediante la fabrica entidad        
            Terrae.Clases.Entidad _persona = Terrae.Clases.FabricaClase.FabricaEntidad.NuevaPersona();
            Terrae.Logica.Comandos.Comando<Terrae.Clases.Entidad> _comando;

            // seteamos los atributos traidos por parametro
            ((Terrae.Clases.Persona)_persona).Usuario = cliente._usuario;
            ((Terrae.Clases.Persona)_persona).Contrasena = cliente._contrasena;

          /*  ((Terrae.Clases.Persona)_persona).Usuario = "maria";
            ((Terrae.Clases.Persona)_persona).Contrasena = "123";*/


            try
            {
                // obtenemos una instancia de la fabrica logica del comando "CrearComandoIniciarSesion"
                _comando = Terrae.Logica.FabricaLogica.FabricaComando.CrearComandoIniciarSesion(_persona);
                // ejecutamos el comando
                _persona = _comando.Ejecutar();
                  // si lo retornado es distinto a null
                  if (_persona != null)
                  {
                      cliente.set_id(((Terrae.Clases.Persona)_persona).Id);
                      cliente.set_nombre(((Terrae.Clases.Persona)_persona).Nombre);
                      cliente._apellido = ((Terrae.Clases.Persona)_persona).Apellido;
                      cliente._fechaNacmiento = ((Terrae.Clases.Persona)_persona).Fecha;
                      cliente._correo = ((Terrae.Clases.Persona)_persona).Correo;
                      cliente._contrasena = ((Terrae.Clases.Persona)_persona).Contrasena;
                      cliente._celular = ((Terrae.Clases.Persona)_persona).Celular;
                     /* cliente.set_id(2);
                      cliente.set_nombre("maria1");
                      cliente._apellido = "martinez";
                      cliente._fechaNacmiento = "30/09/1988";
                      cliente._correo = "Maria@manapro.com";
                      cliente._contrasena = "1235";
                      cliente._celular = "04126177102";*/
                  }
                  else // sino, si es igual a null
                  {
                      cliente = null;
                  }
            }
            catch(NullReferenceException nre)
            {
                _persona = null;
                cliente = null;
                //throw (new NullReferenceException("El objeto referencia es null", nre));
            }
            catch (ArgumentNullException nre)
            {
                _persona = null;
                cliente = null;
               // throw (new ArgumentNullException("El objeto pasado por argumento es null", nre));
            }
            catch (Exception ex)
            {
                _persona = null;
                cliente._correo = ex.ToString();
                //throw new FormatException("Ocurrio un error", ex);
            }

            // verificamos la respuesta
            /*if (_persona == null)
            {
                return null;
            }
            else // sino,
            {*/
                return cliente;
           // }
            
        } // solicitarConfirmacionCliente

        /// <summary>
        /// Implementacion del metodo para registrar un cliente
        /// </summary>
        /// <param name="cliente"></param>
        /// <returns></returns>
        public string solicitarRegistrarCliente(Cliente cliente)
        {
            //Obtenemos una instancia del tipo "Persona" mediante la fabrica entidad        
            Terrae.Clases.Entidad _persona = Terrae.Clases.FabricaClase.FabricaEntidad.NuevaPersona();
            Comando<bool> _comando;
            bool verificar = false;

            (_persona as Terrae.Clases.Persona).Nombre     = cliente._nombre;
            (_persona as Terrae.Clases.Persona).Apellido   = cliente._apellido;
            (_persona as Terrae.Clases.Persona).Fecha      = cliente._fechaNacmiento;
            (_persona as Terrae.Clases.Persona).Correo     = cliente._correo;
            (_persona as Terrae.Clases.Persona).Usuario    = cliente._usuario;
            (_persona as Terrae.Clases.Persona).Contrasena = cliente._contrasena;
            (_persona as Terrae.Clases.Persona).Celular    = cliente._celular;

            try
            {
                //Obtenemos el comando de agregar la persona desde la fabrica lógica.
                _comando = FabricaComando.CrearComandoAgregarPersona(_persona);
                // ejecutamos el comando
                verificar = _comando.Ejecutar();
            }
            catch (NullReferenceException nre)
            {
                verificar = false;
               // throw (new NullReferenceException("El objeto referencia es null", nre));
            }
            catch (ArgumentNullException nre)
            {
                verificar = false;
               // throw (new ArgumentNullException("El objeto pasado por argumento es null", nre));
            }
            catch (Exception ex)
            {
                verificar = false;
            }
            if (verificar)
            {
                return "Bien";
            }
            else{
                return "Mal";
            }
           

        } // solicitarRegistrarCliente

        /// <summary>
        /// Implementacion del metodo para modificar un cliente
        /// </summary>
        /// <param name="cliente"></param>
        /// <returns></returns>
        public string solicitarModificarCliente(Cliente cliente)
        {
            //Obtenemos una instancia del tipo "Persona" mediante la fabrica entidad        
            Terrae.Clases.Entidad _persona = Terrae.Clases.FabricaClase.FabricaEntidad.NuevaPersona();
            Comando<bool> _comando;
            bool verificar = false;

            (_persona as Terrae.Clases.Persona).Nombre = cliente._nombre;
            (_persona as Terrae.Clases.Persona).Apellido = cliente._apellido;
            (_persona as Terrae.Clases.Persona).Fecha = cliente._fechaNacmiento;
            (_persona as Terrae.Clases.Persona).Correo = cliente._correo;
            (_persona as Terrae.Clases.Persona).Usuario = cliente._usuario;
            (_persona as Terrae.Clases.Persona).Contrasena = cliente._contrasena;
            (_persona as Terrae.Clases.Persona).Celular = cliente._celular;

            try
            {
                //Obtenemos el comando de agregar la persona desde la fabrica lógica.
                _comando = FabricaComando.CrearComandoModificarPersona(_persona);
                // ejecutamos el comando
                verificar = _comando.Ejecutar();
            }
            catch (NullReferenceException nre)
            {
                throw (new NullReferenceException("El objeto referencia es null", nre));
            }
            catch (ArgumentNullException nre)
            {
                throw (new ArgumentNullException("El objeto pasado por argumento es null", nre));
            }

            if (verificar)
            {
                return "Bien";
            }
            else
            {
                return "Mal";
            }
           
        }

        public List<String> ListarParametrosXml()
        {

            return new List<string>();
        }

        public List<String> ListarParametrosJson()
        {
            return new List<string>();
        }

        public String EnviarParametroXml(int _idAcceso)
        {
            return ("");
        }

        public String EnviarParametroJson(int _idAcceso)
        {

            return ("Hola carro");
        }

        public String RecepcionParametroXml(int _idAcceso)
        {
            return ("");  
        }

        public String RecepcionParametroJson(int _idAcceso)
        {
            return (""); 
        }

        #endregion Implementacion REST

        #region Implementacion SOAP

        public List<String> ListarParametrosSoap()
        {
            return new List<string>();
        }

        public String ParametroSoap(int _idAcceso)
        {
            return "1";
        }

        public int ProcesarSolicitudSoap(String _parametro)
        {
            return 1;
        }

        #endregion Implementacion SOAP
    }
}
